package com.example.excelimport.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.excelimport.entity.User;
import com.example.excelimport.listener.UserImportListener;
import com.example.excelimport.mapper.UserMapper;
import com.example.excelimport.service.UserImportService;
import com.example.excelimport.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// UserServiceImpl.java
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 批量保存数据 - 带有事务控制
     * 使用@Transactional注解，确保每个批次的原子性
     * propagation = REQUIRES_NEW 为每个批次创建新事务
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void batchSaveWithTransaction(List<User> userList) {
        try {
            userMapper.batchInsert(userList);
        } catch (Exception e) {
            log.error("批量插入失败，数据大小: {}", userList.size(), e);
            throw new RuntimeException("数据插入失败", e);
        }
    }

    /**
     * 方法一：使用监听器模式导入 - 增加文件检查
     */
    @Override
    public void importByListener(String filePath) {
        // 检查文件是否存在
        if (!Files.exists(Paths.get(filePath))) {
            throw new RuntimeException("文件不存在: " + filePath);
        }

        long startTime = System.currentTimeMillis();

        try {
            // 创建监听器并读取Excel
            UserImportListener listener = new UserImportListener(this);
            EasyExcel.read(filePath, User.class, listener)
                    .sheet()
                    .headRowNumber(1)
                    .doRead();

            long endTime = System.currentTimeMillis();
            log.info("监听器模式导入完成，耗时: {} 秒", (endTime - startTime) / 1000.0);
        } catch (Exception e) {
            log.error("导入失败，文件路径: {}", filePath, e);
            throw new RuntimeException("Excel导入失败: " + e.getMessage(), e);
        }
    }

    /**
     * 方法二：使用分页读取模式导入 - 增加文件检查
     */
    @Override
    public void importByPageRead(String filePath) {
        // 检查文件是否存在
        if (!Files.exists(Paths.get(filePath))) {
            throw new RuntimeException("文件不存在: " + filePath);
        }

        long startTime = System.currentTimeMillis();

        try {
            UserImportService importService = new UserImportService();
            importService.setUserService(this);
            importService.importByPageRead(filePath);

            long endTime = System.currentTimeMillis();
            log.info("分页读取模式导入完成，耗时: {} 秒", (endTime - startTime) / 1000.0);
        } catch (Exception e) {
            log.error("导入失败，文件路径: {}", filePath, e);
            throw new RuntimeException("Excel导入失败: " + e.getMessage(), e);
        }
    }

    /**
     * 清除所有用户数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public long clearAllData() {
        // 先获取记录数用于返回
        long count = this.count();

        if (count > 0) {
            // 使用 MyBatis Plus 的删除方法
            this.remove(null);
            log.info("清除所有用户数据，共 {} 条记录", count);
        }

        return count;
    }

    /**
     * 按条件清除数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public long clearDataByCondition(String department, String startDate, String endDate) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        // 构建查询条件
        if (StringUtils.hasText(department)) {
            queryWrapper.eq("department", department);
        }

        if (StringUtils.hasText(startDate)) {
            queryWrapper.ge("hire_date", startDate);
        }

        if (StringUtils.hasText(endDate)) {
            queryWrapper.le("hire_date", endDate);
        }

        // 获取符合条件的记录数
        long count = this.count(queryWrapper);

        if (count > 0) {
            // 执行删除
            this.remove(queryWrapper);
            log.info("条件清除数据成功，条件: department={}, startDate={}, endDate={}, 共 {} 条记录",
                    department, startDate, endDate, count);
        }

        return count;
    }

    /**
     * 重置表（TRUNCATE TABLE）
     * 注意：这会删除所有数据并重置自增ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetTable() {
        userMapper.truncateTable();
        log.info("用户表重置成功，自增ID已重置");
    }

    /**
     * 获取数据统计信息
     */
    @Override
    public Map<String, Object> getDataStats() {
        Map<String, Object> stats = new HashMap<>();

        // 总记录数
        long totalCount = this.count();
        stats.put("totalCount", totalCount);

        // 各部门统计
        List<Map<String, Object>> departmentStats = userMapper.countByDepartment();
        stats.put("departmentStats", departmentStats);

        // 年龄统计
        Map<String, Object> ageStats = userMapper.getAgeStatistics();
        stats.put("ageStats", ageStats);

        // 最新记录时间
        User latestUser = this.getOne(new QueryWrapper<User>().orderByDesc("create_time").last("LIMIT 1"));
        if (latestUser != null) {
            stats.put("latestRecordTime", latestUser.getCreateTime());
        }

        log.info("数据统计信息获取成功，总记录数: {}", totalCount);
        return stats;
    }

}
